package by.apiskun.curex.dataaccess.impl;

import java.util.List;

import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.apache.commons.lang3.Validate;
import org.springframework.stereotype.Repository;

import by.apiskun.curex.dataaccess.MoneyDAO;
import by.apiskun.curex.datamodel.Money;
import by.apiskun.curex.datamodel.Money_;

@Repository
public class MoneyDAOImpl extends AbstractDAOImpl<Long, Money> implements
		MoneyDAO {
	protected MoneyDAOImpl() {
		super(Money.class);
	}

	@Override
	public Long getCount() {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Long> criteria = cBuilder.createQuery(Long.class);
		Root<Money> root = criteria.from(Money.class);

		criteria.select(cBuilder.count(root));

		TypedQuery<Long> query = getEm().createQuery(criteria);
		return query.getSingleResult();
	}

	@Override
	public List<Money> getAllMoney() {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Money> criteria = cBuilder.createQuery(Money.class);
		Root<Money> root = criteria.from(Money.class);

		criteria.select(root);

		TypedQuery<Money> query = getEm().createQuery(criteria);
		List<Money> results = query.getResultList();
		return results;
	}

	@Override
	public List<Money> getAllMoneyByName(String name) {
		CriteriaBuilder cBuilder = getEm().getCriteriaBuilder();

		CriteriaQuery<Money> root = cBuilder.createQuery(Money.class);
		Root<Money> criteria = root.from(Money.class);

		root.select(criteria);
		root.where(cBuilder.equal(criteria.get(Money_.moneyName), name));

		TypedQuery<Money> query = getEm().createQuery(root);
		List<Money> results = query.getResultList();
		return results;
	}

	@Override
	public void updateMoneyName(Long id, String newName) {
		String q = String.format(
				"update from %s p set p.moneyName=:newParam where p.id=:id",
				Money.class.getSimpleName());
		Query updateQuery = getEm().createQuery(q);
		updateQuery.setParameter("newParam", newName);
		updateQuery.setParameter("id", id);
		int updatedRowsCount = updateQuery.executeUpdate();
		Validate.isTrue(updatedRowsCount == 1, "One row should be updated");
	}

}
